package com.sdu.shanyimisapi.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.MD5;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.sdu.shanyimisapi.common.PageUtils;
import com.sdu.shanyimisapi.db.dao.AppUserDao;
import com.sdu.shanyimisapi.db.pojo.AppUserEntity;
import com.sdu.shanyimisapi.exception.ShanyiMisException;
import com.sdu.shanyimisapi.service.AppUserService;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
 * @author lihaopeng
 * @version 1.0
 * @project shanyi-mis-api
 * @description App用户
 * @since 2024/4/13 22:03
 */
@Service
@Slf4j // 加上这个注解，就可以在这个类里做日志输出了，使用log.info()、log.error()等方法
public class AppUserServiceImpl implements AppUserService {

    @Value("${minio.endpoint}")
    private String endpoint;

    @Value("${minio.access-key}")
    private String accessKey;

    @Value("${minio.secret-key}")
    private String secretKey;

    @Resource
    private AppUserDao appUserDao;

//    @Resource
//    private AppUserActivityDao appUserActivityDao;

    /**
     * 分页查询App用户
     *
     * @param param
     * @return
     */
    @Override
    public PageUtils searchByPage(Map param) {
        ArrayList<HashMap> list = null;
        long count = appUserDao.countAppUser(param);
        if (count > 0) {
            list = appUserDao.searchByPage(param);
        } else {
            list = new ArrayList<>(); // 如果没有数据，就返回一个空的ArrayList
        }
        int page = MapUtil.getInt(param, "page");
        int length = MapUtil.getInt(param, "length");
        PageUtils pageUtils = new PageUtils(list, count, page, length);
        return pageUtils;
    }

    /**
     * 根据ID查询App用户
     *
     * @param id App用户id
     * @return
     */
    @Override
    public HashMap searchById(int id) {
        HashMap map = appUserDao.searchById(id);
        JSONArray likes = JSONUtil.parseArray(MapUtil.getStr(map, "likes"));
        map.replace("likes", likes);
        JSONArray dislikes = JSONUtil.parseArray(MapUtil.getStr(map, "dislikes"));
        map.replace("dislikes", dislikes);
        return map;
    }


    /**
     * 更新App用户头像
     *
     * @param file
     * @param id
     */
    @Override
    @Transactional
    public void updateAvatar(MultipartFile file, Integer id) {
        try {

            log.info("上传头像，id={}", id);
            String filename = "app-user-" + id + ".jpg";
            // 在Minio中保存用户头像
            MinioClient client = new MinioClient.Builder().endpoint(endpoint)
                    .credentials(accessKey, secretKey).build();
            client.putObject(PutObjectArgs.builder().bucket("shanyi")
                    .object("shanyi-mis/avatar/" + filename)
                    .stream(file.getInputStream(), -1, 5 * 1024 * 1024) // 上传大小不能超过5M
                    .contentType("image/jpeg").build()); // 上传的文件类型是jpeg（即jpg）

            // 更新App用户表中的avatar字段
            appUserDao.updateAvatar(new HashMap() {
                {
                    put("id", id);
                    put("avatar", "/shanyi-mis/avatar/" + filename);
                }
            });
        } catch (Exception e) {
            log.error("上传头像失败", e);
            throw new ShanyiMisException("上传头像失败");
        }
    }

    /**
     * 新增App用户
     *
     * @param param
     */
    @Override
    public void insertAppUser(Map param) {

        // getStr()可以从Map里获取出字符串
        String username = MapUtil.getStr(param,"username");
        String password = MapUtil.getStr(param,"password");

        // 查询App用户名是否被占用
        int count = appUserDao.countAppUserByUsername(username);

        if (count > 0) {
            throw new ShanyiMisException("用户名已被占用！");
        }


        // 处理密码
        MD5 md5 = MD5.create();
        String temp = md5.digestHex(username);
        // 前六位字符
        String tempStart = StrUtil.subWithLength(temp,0,6);
        // 后三位字符
        String tempEnd = StrUtil.subSuf(temp,temp.length() - 3);
        // 混淆原始密码并哈希加密
        password = md5.digestHex(tempStart + password + tempEnd);
        param.replace("password", password);

        // 计算bmi
        double height = MapUtil.getDouble(param, "height");
        double weight = MapUtil.getDouble(param, "weight");
        double bmi = weight / (height * height);
        // 保留两位小数
        bmi = (double) Math.round(bmi * 100) / 100;
        param.put("bmi", bmi);

        // 保存App用户
        AppUserEntity appUserEntity = BeanUtil.toBean(param, AppUserEntity.class);
        appUserDao.insertAppUser(appUserEntity);

        // 根据App用户username查询App用户id
//        Integer appUserId = appUserDao.searchIdByUsername(appUserEntity.getUsername());

        // 保存App用户与（日常打卡）活动关系
//        AppUserActivityEntity appUserActivityEntity = new AppUserActivityEntity();
//        appUserActivityEntity.setAppUserId(appUserId);
//        appUserActivityEntity.setAppActivityId(1); // 日常打卡活动id为1
//        appUserActivityDao.insertAppUserActivity(appUserActivityEntity);

    }

    /**
     * 更新App用户
     *
     * @param param
     */
    @Override
    @Transactional
    public void updateAppUser(Map param) {
        // 计算bmi
        double height = MapUtil.getDouble(param, "height");
        double weight = MapUtil.getDouble(param, "weight");
        double bmi = weight / (height * height);
        // 保留两位小数
        bmi = (double) Math.round(bmi * 100) / 100;
        param.put("bmi", bmi);

        // 更新App用户
        appUserDao.updateAppUser(param);
    }

    /**
     * 删除App用户
     *
     * @param ids
     */
    @Override
    @Transactional
    public void deleteAppUser(Integer[] ids) {
        appUserDao.deleteAppUser(ids);
    }

}
